package com.ruoyi.ftrl.io.server.common;

import org.apache.commons.lang3.ArrayUtils;

import java.io.*;

/**
 * 字节数组互相转换
 */
public class ByteUtil {
    /** * 16进制字符集 */
    private static final char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
            'e', 'f' };

    private static final String HEXS = "0123456789abcdef";

    /** * 将一个字节数组转换成一个int */
    public static int toInt(byte[] bytes) {
        int i = 24;
        int result = 0;
        for (byte tmp : bytes) {
            result += (tmp & 0xff) << i;
            i -= 8;
        }
        return result;
    }

    /**
     * 高位字节在前
     * @param n
     * @return
     */
    public static byte[] intToHighByteArr(int n) {
        byte[] b = new byte[4];
        b[3] = (byte) (n & 0xff);
        b[2] = (byte) (n >> 8 & 0xff);
        b[1] = (byte) (n >> 16 & 0xff);
        b[0] = (byte) (n >> 24 & 0xff);
        return b;
    }

    /**
     * 高位字节在前
     * @param n
     * @return
     */
    public static byte[] shortToHighByteArr(short n) {
        byte[] b = new byte[2];
        b[1] = (byte) (n & 0xff);
        b[0] = (byte) (n >> 8 & 0xff);
        return b;
    }


    /**
     * 从一个byte[]数组中截取一部分
     * @param src
     * @param begin
     * @param count
     * @return
     */
    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        for (int i=begin;i<begin+count; i++) {
            bs[i-begin] = src[i];
        }
        return bs;
    }

    /**
     * 更新src数组
     * @param des
     * @param desPos
     * @param count
     * @return
     */
    public static byte[] modifyBytes(byte[] src,byte[] des, int desPos, int count) {
        System.arraycopy(src,0,des,desPos,count);
        return des;
    }


    /** * 将一个字节数组转换成一个short */
    public static short toShort(byte[] bytes) {
        int i = 8;
        short result = 0;
        for (byte tmp : bytes) {
            result += (tmp & 0xff) << i;
            i -= 8;
        }
        return result;
    }

    public static String toVersion(byte[] bytes){
        StringBuffer stringBuffer = new StringBuffer("V");
        for (int i =0 ; i< bytes.length; i++){
            if (i>0){
                stringBuffer.append(".");
            }
            stringBuffer.append(bytes[i]);
        }
        return stringBuffer.toString();
    }

    /**
     * @功能: BCD码转为10进制串(阿拉伯数字)
     * @参数: BCD码  4位（bit）存一个十进制的0 1 2 3 4 5 6 7 8 9 数字
     * @结果: 10进制串
     */
    public static String bcd2Str(byte[] bytes) {
        StringBuffer temp = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
            temp.append((byte) (bytes[i] & 0x0f));
        }
        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp
                .toString().substring(1) : temp.toString();
    }

    /**
     * @功能: BCD码转为10进制串(阿拉伯数据)
     * @参数: BCD码
     * @结果: 10进制串
     */
    public static String bcd62Str(byte[] bytes) {
        byte[] prefix = {0x20};
        byte[] all = ArrayUtils.addAll(prefix, bytes);
        return ByteUtil.bcd2Str(all);
    }


    /**
     * * 将字节数组中指定区间的子数组转换成16进制字符串 * @param bytes 目标字节数组 * @param start
     * 起始位置（包括该位置） * @param end 结束位置（不包括该位置） * @return 转换结果
     */
    public static String bytesToHex(byte bytes[], int start, int end) {
        StringBuilder sb = new StringBuilder();
        for (int i = start; i < start + end; i++) {
            sb.append(byteToHex(bytes[i]));
        }
        return sb.toString();
    }

    /**
     * hexStr:010400xxxx
     * @param bytes
     * @return
     */
    public static String bytesToHex(byte bytes[]) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            sb.append(byteToHex(bytes[i]));
        }
        return sb.toString();
    }

    /**
     * 用作hex字符串的生成
     * byte[]转hex字符串
     * @param array
     * @return
     */
    public static String bytes2HexString(byte[] array) {
        StringBuilder builder = new StringBuilder();

        for (byte b : array) {
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            if (hex.startsWith("8") || hex.startsWith("9") || hex.startsWith("a") || hex.startsWith("b")  || hex.startsWith("c") || hex.startsWith("d") || hex.startsWith("e") || hex.startsWith("f")){
                builder.append("(byte)");
            }
            builder.append("0x").append(hex).append(",");
        }

        return builder.toString();
    }
    public static String addOneToHex(String hex) {
        char[] hexArray = hex.toCharArray();
        int index = hex.length() - 1;

        while(index >= 0) {
            if(hexArray[index] != 'F') {
                hexArray[index] += 1;
                break;
            } else {
                hexArray[index] = '0';
                index--;
            }
        }

        if(index < 0) {
            return "1" + new String(hexArray);
        } else {
            return new String(hexArray);
        }
    }


    //byte[]转hex字符串 `
    public static String idcardHex(byte[] array) {
        StringBuilder builder = new StringBuilder();

        for (byte b : array) {
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() > 1) {
                throw new NumberFormatException("格式不正确");
            }
            builder.append(hex);
        }

        return builder.toString();
    }

    /** * 将单个字节码转换成16进制字符串 * @param bt 目标字节 * @return 转换结果 */
    public static String byteToHex(byte bt) {
        return HEX_DIGITS[(bt & 0xf0) >> 4] + "" + HEX_DIGITS[bt & 0xf];
    }

    /**
     * 将16进制转换成字节数组
     *
     * @param hex
     * @return
     */
    public static byte[] xhexToBytes(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (hexToByte(achar[pos]) << 4 | hexToByte(achar[pos + 1]));
        }
        return result;
    }
    // 将十六进制字符串转换为字节数组
    public static byte[] hexStringToByteArray(String hexString) {
        int len = hexString.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }
        return data;
    }

    /**
     * 16进制bcd转byte
     * @param hexString
     * @return
     */
    public static byte[] bcdStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("") || hexString.length() % 2 != 0) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) * 10 + charToByte(hexChars[pos + 1]));
        }
        return d;
    }
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
    /**
     * 将一个16进制转换成字节数组
     *
     * @param c
     * @return
     */
    public static byte hexToByte(char c) {
        return (byte) HEXS.indexOf(c);
    }

    /**
     * 从对象获取一个字节数组
     *
     */
    public static byte[] obj2Byte(Serializable obj) {
        if (obj == null) {
            return null;
        }
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = null;
        byte[] result = null;
        try {
            oo = new ObjectOutputStream(bo);
            oo.writeObject(obj);
            result = bo.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (oo != null) {
                try {
                    oo.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * 从字节数组获取对象
     * 
     */
    public static Object byte2Obj(byte[] objBytes) {
        if (objBytes == null || objBytes.length == 0) {
            return null;
        }
        ByteArrayInputStream bi = new ByteArrayInputStream(objBytes);
        ObjectInputStream oi = null;
        Object obj = null;
        try {
            oi = new ObjectInputStream(bi);
            obj = oi.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (oi != null) {
                try {
                    oi.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return obj;
    }

}
